package com.xnyzc.lhy.order.mq.consumer;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xnyzc.lhy.common.component.config.security.RocketConfig;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.MqConstant;
import com.xnyzc.lhy.common.constant.MqConsumerGroupConstant;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.ParameterEnum;
import com.xnyzc.lhy.common.exception.DiDiException;
import com.xnyzc.lhy.common.penum.EDiDiErrorCode;
import com.xnyzc.lhy.common.penum.EDispatchType;
import com.xnyzc.lhy.common.penum.order.EDiDiOrderStatus;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.order.entity.dictionaries.OaSysDict;
import com.xnyzc.lhy.order.entity.mq.OrderParam;
import com.xnyzc.lhy.order.entity.order.OaCOrderPersonal;
import com.xnyzc.lhy.order.entity.order.VehicleType;
import com.xnyzc.lhy.order.entity.system.OaSysDispatchLog;
import com.xnyzc.lhy.order.feign.amap.IAmapService;
import com.xnyzc.lhy.order.mapper.dictionaries.OaSysDictMapper;
import com.xnyzc.lhy.order.mapper.order.OaCOrderPersonalMapper;
import com.xnyzc.lhy.order.mapper.system.OaSysOrderDispatchRecordMapper;
import com.xnyzc.lhy.order.mq.MqDispatchLogProducer;
import com.xnyzc.lhy.order.mq.MqOrderProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * 创建订单
 *
 * @author zhengxu
 */
@Slf4j
@Component
public class MqDidiCreateOrderConsumer {
    private DefaultMQPushConsumer consumer;

    @Autowired
    RocketConfig config;

    @Autowired
    RedisCommon redisCommon;

    @Autowired
    MqOrderProducer mqOrderProducer;

    @Autowired
    OaSysDictMapper oaSysDictMapper;

    @Autowired
    IAmapService iAmapService;

    @Value("${rocketMq.isStart}")
    private boolean isStart;

    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;
    @Autowired
    OaSysOrderDispatchRecordMapper oaSysOrderDispatchRecordMapper;

    @Autowired
    MqDispatchLogProducer dispatchLogProducer;

    /**
     * 开启监听
     */
    @PostConstruct
    public void init() {
        try {
            if (!isStart) {
                return;
            }
            consumer = new DefaultMQPushConsumer(MqConsumerGroupConstant.CREATE_ORDER);
            consumer.subscribe(config.getTopic(), MqConstant.DIDI_CREATE_ORDER);
            consumer.setNamesrvAddr(config.getNameServerAddr());
            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
            consumer.setConsumeMessageBatchMaxSize(1);
            consumer.registerMessageListener(new MessageListenerConcurrently() {
                @Override
                public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
                    MessageExt messageExt = msgs.get(0);
                    return MqDidiCreateOrderConsumer.this.dealBody(messageExt);
                }
            });
            consumer.start();
            log.info("---------创建订单消费者启动完成-----o(*^▽^*)┛-------");
        } catch (Exception e) {
            log.info("---------创建订单消费者初始化失败----(# ﾟДﾟ)--------");
        }
    }

    /**
     * 处理业务逻辑
     *
     * @param messageExt
     * @return
     */
    public ConsumeConcurrentlyStatus dealBody(MessageExt messageExt) {
        try {
            //发送的消息
            String dataStr = new String(messageExt.getBody());
            if (CheckUtil.strIsEmpty(dataStr)) {
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
            OrderParam createOrderParam = JSON.parseObject(dataStr, OrderParam.class);

            int cnt = 2;
            while (cnt > 0) {
                //延迟300毫秒秒继续创建订单
                try {
                    if (cnt < 2) {
                        Thread.sleep(500);
                    }
                } catch (InterruptedException e) {
                    log.error(e.getMessage());
                    throw e;
                }
                cnt--;
                /**
                 * ############## 开始创建订单#############
                 */


                // 获取估价单
                log.info("获取的预估价格ID为" + createOrderParam.getEstimateId());
                String estimateKey = RedisPrefixConstant.DIDI_ESTIMATE + createOrderParam.getEstimateId();
                HashMap<String, Object> hashMap = redisCommon.getHashMap(estimateKey);
                // 生成订单
//                long personalId =;
                OaCOrderPersonal oaCOrderPersonal = new OaCOrderPersonal();
                try {
                    oaCOrderPersonal.setEstimateTime(new BigDecimal(hashMap.get("driverMinute").toString()));
                    oaCOrderPersonal.setEstimateDistance(new BigDecimal(hashMap.get("driverMetre").toString()));
                    // 服务产品线
                    if(hashMap.get("productType")!=null){
                        oaCOrderPersonal.setProductType(hashMap.get("productType").toString());
                    }
                    // 城市code
                    oaCOrderPersonal.setCityId(hashMap.get("cityCode").toString());
                    // 查询类型
                    oaCOrderPersonal.setRulesId(Long.valueOf(hashMap.get("rulesId").toString()));
                    List<OaSysDict> dictList = getDict(hashMap.get("rideType").toString());
                    if (dictList.isEmpty()) {
                        log.info("创建订单时，获取城市信息出错，城市信息为：{" + dictList.toString() + "}");
                        continue;
                    }
                    oaCOrderPersonal.setVehicleType(Integer.parseInt(dictList.get(0).getValue()));
                    // 预估ID
                    oaCOrderPersonal.setEstimateId(Long.valueOf(createOrderParam.getEstimateId()));
                    // 起步价
                    BigDecimal startFee = new BigDecimal(hashMap.get("startFee").toString());
                    oaCOrderPersonal.setStartFee(startFee);
                    //总金额
                    oaCOrderPersonal.setTotalFee(startFee);
                    //设置起步价抽成后的费用
                    oaCOrderPersonal.setDrawFee(new BigDecimal(hashMap.get("drawFee").toString()));
                    // 预估里程费
                    oaCOrderPersonal.setEstimateNormalFee(new BigDecimal(hashMap.get("specialDistanceFee").toString()));
                    // 预估时长费
                    oaCOrderPersonal.setEstimateTimeFee(new BigDecimal(hashMap.get("specialTimeFee").toString()));
                    // 预估远途行驶距离
                    oaCOrderPersonal.setEstimateEmptyDistance(new BigDecimal(hashMap.get("emptyDistance").toString()));
                    // 预估计价行驶距离
                    BigDecimal specialDistance = new BigDecimal(hashMap.get("specialDistance").toString()).divide(new BigDecimal(1000));
                    oaCOrderPersonal.setEstimateNormalDistance(specialDistance);
                    // 预估普通时段计费时间, 单位秒(s)
                    BigDecimal specialTime = new BigDecimal(hashMap.get("specialTime").toString()).divide(new BigDecimal(60));
                    oaCOrderPersonal.setEstimateNormalTime(specialTime);
                    // 预估远途费
                    oaCOrderPersonal.setEstimateEmptyFee(new BigDecimal(hashMap.get("emptyFee").toString()));
                    // 预估特殊时段费
                    oaCOrderPersonal.setEstimateTimeRateFee(new BigDecimal(hashMap.get("timeRateFee").toString()));
                    // 高峰期加价
                    oaCOrderPersonal.setPeakAddFee(new BigDecimal(hashMap.get("urgent_fee").toString()));
                    // 预估总价格 保留两位小数
                    oaCOrderPersonal.setEstimatePrice(new BigDecimal(hashMap.get("totalFee").toString()).setScale(2, BigDecimal.ROUND_HALF_DOWN).toString());
                    // 基础费
                    oaCOrderPersonal.setBaseFee(new BigDecimal(hashMap.get("limit_fee").toString()));
                    // 基础费补足
                    oaCOrderPersonal.setBaseSupplementFee(new BigDecimal(hashMap.get("limit_pay").toString()));
                    // 起始经纬度地址
                    String startLng = hashMap.get("startLng").toString();
                    String startLat = hashMap.get("startLat").toString();
                    String endLng = hashMap.get("endLng").toString();
                    String endLat = hashMap.get("endLat").toString();
                    log.info("被滴滴调用======我来获取开始地址的逆地理编码，我准备开始获取了");
                    String regeo = iAmapService.getRegeo(startLng + "," + startLat + "|" + endLng + "," + endLat);
                    log.info("被滴滴调用======我来获取开始地址的逆地理编码，我调用成功了，数据为：" + regeo);
                    regeo = regeo.replaceAll("\"", "");
                    if (CheckUtil.strIsEmpty(regeo)) {
                        throw DiDiException.create(EDiDiErrorCode.parameterError);
                    }
                    log.info("被滴滴调用======逆地理编码返回结果不为空，继续");
                    String[] split = regeo.split(":");
                    if (split.length != 2) {
                        throw DiDiException.create(EDiDiErrorCode.parameterError);
                    }
                    oaCOrderPersonal.setStartLng(startLng);
                    oaCOrderPersonal.setStartLat(startLat);
                    oaCOrderPersonal.setStartAddress(split[0]);
                    oaCOrderPersonal.setClat(startLat);
                    oaCOrderPersonal.setClng(startLng);
                    // 目的地经纬度地址
                    oaCOrderPersonal.setEndLng(endLng);
                    oaCOrderPersonal.setEndLat(endLat);
                    if(hashMap.get("endAddress")!=null){
                        oaCOrderPersonal.setEndAddress(hashMap.get("endAddress").toString());
                    }else {
                        oaCOrderPersonal.setEndAddress(split[1]);
                    }
                    // 用车时间  departureTime
                    // ID
                } catch (Exception e) {
                    log.error("捕获到异常信息，异常信息为：" + e.getMessage());
                    log.error("自定义异常信息为：" + EDiDiErrorCode.getListOfValuationIsNull.toChString());
                    continue;
                }
                // 订单orderNo
                String orderNo = createOrderParam.getOrderNo();
                oaCOrderPersonal.setOrderNo(orderNo);
                oaCOrderPersonal.setPersonalId(createOrderParam.getPersonalId());
                Date date = new Date();
                oaCOrderPersonal.setCreateTime(date);
                oaCOrderPersonal.setUpdateTime(date);
                oaCOrderPersonal.setCreateUser(createOrderParam.getUserId().toString());
                oaCOrderPersonal.setUpdateUser(createOrderParam.getOpen_pid());
                oaCOrderPersonal.setUserId(createOrderParam.getUserId());
                oaCOrderPersonal.setTag(createOrderParam.getTag());
                log.info("滴滴传递的用户ID为：" + createOrderParam.getOpen_pid());
                oaCOrderPersonal.setDidiUserId(createOrderParam.getOpen_pid());
                oaCOrderPersonal.setPassengerPhone(createOrderParam.getUphone());
                oaCOrderPersonal.setPassengerPhoneSuffix(createOrderParam.getUphone().substring(createOrderParam.getUphone().length()-4,createOrderParam.getUphone().length()));
                // 滴滴订单ID
                oaCOrderPersonal.setDidiOrderId(createOrderParam.getOpen_oid());
                try {
                    // 滴滴订单状态
                    oaCOrderPersonal.setDidiOrderStatus(EDiDiOrderStatus.waitingResponse.getDidiType());
                    // 订单状态
                    oaCOrderPersonal.setOrderStatus(EDiDiOrderStatus.waitingResponse.getType());
                } catch (Exception e) {
                    log.error("捕获到异常信息，异常信息为：" + e.getMessage());
                    log.error("自定义异常信息为：" + EDiDiErrorCode.notOrderStatus.toChString());
                    continue;
                }
                int insert = 0;
                try {
                    int orderNum = oaCOrderPersonalMapper.selectNumByOrderNoAndDidiId(orderNo, createOrderParam.getOpen_oid());
                    if (orderNum > 0) {
                        log.error("异常情况，创建订单ID（orderNo/didiOrderId）数据库中已存在，请核实！！！");
                        continue;
                    } else {
                        insert = oaCOrderPersonalMapper.insert(oaCOrderPersonal);
                    }
                } catch (Exception e) {
                    log.error("捕获到异常信息，异常信息为：" + e.getMessage());
                    log.error("自定义异常信息为：" + EDiDiErrorCode.orderPersonalInsertFail.toChString());
                    continue;
                }
                if (insert < 1) {
                    log.error("创建订单失败，插入数据" + insert + "条，自定义异常信息为：" + EDiDiErrorCode.notOrderStatus.toChString());
                    continue;
                }
                com.xnyzc.lhy.order.entity.param.order.OrderParam orderParam = new com.xnyzc.lhy.order.entity.param.order.OrderParam();
                /* #######推给mq###### */
                // 经纬度
                orderParam.setFlat(oaCOrderPersonal.getStartLat());
                orderParam.setFlng(oaCOrderPersonal.getStartLng());
                orderParam.setTlat(oaCOrderPersonal.getEndLat());
                orderParam.setTlng(oaCOrderPersonal.getEndLng());
                orderParam.setStartAddress(oaCOrderPersonal.getStartAddress());
                orderParam.setEndAddress(oaCOrderPersonal.getEndAddress());
                orderParam.setTag(oaCOrderPersonal.getTag());
                // 预估ID
                orderParam.setEstimateId(createOrderParam.getEstimateId());
                // 订单信息
                orderParam.setOrderNo(oaCOrderPersonal.getOrderNo());

                orderParam.setOpenOid(createOrderParam.getOpen_oid());
                //获取城市Code
                orderParam.setCityId(hashMap.get("cityCode").toString());
                orderParam.setProductType(oaCOrderPersonal.getProductType());
                orderParam.setRideType(hashMap.get("rideType").toString());
                orderParam.setPassengerPhone(oaCOrderPersonal.getPassengerPhone());
                // 叫车类型数据源
                List<VehicleType> typeList = new ArrayList<>();
                VehicleType vehicleType = new VehicleType();
                vehicleType.setType(ParameterEnum.ZERO.getType());
                vehicleType.setNumber(ParameterEnum.ONE.getType());
                typeList.add(vehicleType);
                orderParam.setTypeList(typeList);
                // 保存order数据
                log.info("创建订单成功");
                log.info("存入Redis，存入数据为：" + JSON.toJSONString(oaCOrderPersonal));
                redisCommon.set(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrderPersonal.getOrderNo(), JSON.toJSONString(oaCOrderPersonal));
                log.info("存入Redis成功，验证是否有数据" + redisCommon.hashKey(RedisPrefixConstant.ORDER_OA_D_ORDER + oaCOrderPersonal.getOrderNo()));
                try {
                    OaSysDispatchLog dispatchLog = new OaSysDispatchLog();
                    dispatchLog.setDdOpenId(oaCOrderPersonal.getDidiOrderId());
                    String startLng = oaCOrderPersonal.getStartLng();
                    String startLat = oaCOrderPersonal.getStartLat();
                    if (CheckUtil.objIsNotEmpty(startLng)) {
                        dispatchLog.setPassengerLng(Double.valueOf(startLng));
                    }
                    if (CheckUtil.objIsNotEmpty(startLat)) {
                        dispatchLog.setPassengerLat(Double.valueOf(startLat));
                    }
                    dispatchLog.setOrderId(orderNo);
                    dispatchLog.setCityId(hashMap.get("cityCode").toString());
                    dispatchLog.setTimestamp(System.currentTimeMillis());
                    dispatchLog.setLogId(IDUtil.nextId());
                    dispatchLogProducer.sendMsg(dispatchLog, EDispatchType.createOrderAfter.getDesc());
                    log.info("dispatch_log 创建订单完成,订单号:{}", hashMap.get("estimateId").toString());
                } catch (Exception e) {
                    log.error("记录订单调度日志!");
                }
                // 订单调度
                System.out.println("DIDIDIDIDI------------" + System.currentTimeMillis() + "-------------------");
                mqOrderProducer.sendMsg(orderParam);
                log.info("给mq发送数据");


                /**
                 * ############## 结束创建订单#############
                 */
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        } catch (Exception e) {
            log.error("滴滴调用创建订单失败");
            throw DiDiException.create(EDiDiErrorCode.orderCreateFail);
        }
    }

    /**
     * 查询字典
     *
     * @param type
     * @return
     */
    public List<OaSysDict> getDict(String type) {
        QueryWrapper<OaSysDict> dictWrapper = new QueryWrapper<>();
        dictWrapper.eq(OaSysDict.EXPAND1, type);
        dictWrapper.eq(OaSysDict.TYPE, "require_level");
        List<OaSysDict> dictList = oaSysDictMapper.selectList(dictWrapper);
        return dictList;
    }
}
